package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.example.constant.Constant;
import com.example.dao.Oauth2RegisteredClientDao;
import com.example.dto.*;
import com.example.entity.Oauth2RegisteredClientEntity;
import com.example.feign.RegisteredClientFeignClient;
import com.example.model.api.Result;
import com.example.model.page.PageData;
import com.example.mybatis.service.impl.BaseServiceImpl;
import com.example.service.Oauth2RegisteredClientService;
import com.example.utils.ConvertUtils;
import com.example.utils.JsonUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * OAuth2客户端应用
 */
@Service
public class Oauth2RegisteredClientServiceImpl extends BaseServiceImpl<Oauth2RegisteredClientDao, Oauth2RegisteredClientEntity> implements Oauth2RegisteredClientService {
    @Autowired
    private RegisteredClientFeignClient registeredClientFeignClient;
    @Override
    public LambdaQueryWrapper<Oauth2RegisteredClientEntity> getWrapper(Oauth2RegisteredClientQueryDTO params) {
        LambdaQueryWrapper<Oauth2RegisteredClientEntity> wrapper = new LambdaQueryWrapper<>();
        
        wrapper.like(StringUtils.isNotBlank(params.getClientId()), Oauth2RegisteredClientEntity::getClientId, params.getClientId());
        wrapper.like(StringUtils.isNotBlank(params.getClientName()), Oauth2RegisteredClientEntity::getClientName, params.getClientName());
        wrapper.eq(params.getStoreId() != null, Oauth2RegisteredClientEntity::getStoreId, params.getStoreId());
        
        return wrapper;
    }

    @Override
    public PageData<Oauth2RegisteredClientDTO> selectPage(Oauth2RegisteredClientQueryDTO params) {
        Map<String, Object> param = JsonUtils.convertClassToMap(params);
        IPage<Oauth2RegisteredClientEntity> page = baseDao.selectPage(
                getPage(param, Constant.CREATE_DATE, false),
                getWrapper(params)
        );
        return getPageData(page, Oauth2RegisteredClientDTO.class);
    }

    @Override
    public List<Oauth2RegisteredClientDTO> list(Oauth2RegisteredClientQueryDTO params) {
        List<Oauth2RegisteredClientEntity> entityList = baseDao.selectList(getWrapper(params));
        
        return ConvertUtils.sourceToTarget(entityList, Oauth2RegisteredClientDTO.class);
    }

    @Override
    public Integer getIsBusinessUser(String id) {
        Oauth2RegisteredClientEntity oauth2RegisteredClientEntity = super.selectById(id);
        Integer isBusinessUser = oauth2RegisteredClientEntity.getIsBusinessUser();
        return isBusinessUser;
    }
    @Override
    public Oauth2RegisteredClientDTO get(String id) {
        Result<Oauth2RegisteredClientDTO> oauth2RegisteredClientDTOResult = registeredClientFeignClient.get(id);
        Oauth2RegisteredClientDTO data = oauth2RegisteredClientDTOResult.getData();
        Oauth2RegisteredClientEntity oauth2RegisteredClientEntity = super.selectById(id);
        Date createDate = oauth2RegisteredClientEntity.getCreateDate();
        Long creator = oauth2RegisteredClientEntity.getCreator();
        Date updateDate = oauth2RegisteredClientEntity.getUpdateDate();
        Long updator = oauth2RegisteredClientEntity.getUpdator();
        Long storeId = oauth2RegisteredClientEntity.getStoreId();
        Integer isBusinessUser = oauth2RegisteredClientEntity.getIsBusinessUser();
        data.setCreateDate(createDate);
        data.setCreator(creator);
        data.setUpdateDate(updateDate);
        data.setUpdator(updator);
        data.setStoreId(storeId);
        data.setClientSecretPlaintext(oauth2RegisteredClientEntity.getClientSecretPlaintext());
        data.setIsBusinessUser(isBusinessUser);
        return data;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(Oauth2RegisteredClientDTO dto) {
        String clientSecretVal = clientSecret();
        dto.setClientId(String.valueOf(snowflake.nextId()));
        dto.setClientSecret(clientSecretVal);
        dto.setClientSecretPlaintext(clientSecretVal);
        saveRegisteredClient(dto);
    }

    private String clientSecret(){
        // 输出一个32字符长的十六进制字符串
        String uuid = java.util.UUID.randomUUID().toString().replace("-", "");
        return DigestUtils.md5Hex(uuid);
    }

    private void saveRegisteredClient(Oauth2RegisteredClientDTO dto) {
        Result<Oauth2RegisteredClientDTO> oauth2RegisteredClientDTOResult = registeredClientFeignClient.saveRegisteredClient(dto);
        dto = oauth2RegisteredClientDTOResult.getData();
        Oauth2RegisteredClientEntity oauth2RegisteredClientEntity = new Oauth2RegisteredClientEntity();
        oauth2RegisteredClientEntity.setId(dto.getId());
        oauth2RegisteredClientEntity.setCreateDate(new Date());
        oauth2RegisteredClientEntity.setStoreId(null);
        oauth2RegisteredClientEntity.setIsBusinessUser(dto.getIsBusinessUser());
        oauth2RegisteredClientEntity.setClientSecretPlaintext(dto.getClientSecretPlaintext());

        super.updateById(oauth2RegisteredClientEntity);
    }


    @Override
    public void updateStoreId(String id, Long storeId){
        Oauth2RegisteredClientEntity oauth2RegisteredClientEntity1 = baseDao.selectOne(new QueryWrapper<Oauth2RegisteredClientEntity>().eq("is_business_user", 0).eq("store_id", storeId));
        if (oauth2RegisteredClientEntity1 != null) {
            baseDao.updateStoreIdByClientid(oauth2RegisteredClientEntity1.getId(), null);
        }
        baseDao.updateStoreIdByClientid(id, storeId);
    }

    @Override
    public Oauth2RegisteredClientEntity getStoreId(Long storeId){
        return baseDao.selectOne(new QueryWrapper<Oauth2RegisteredClientEntity>().eq("is_business_user", 0).eq("store_id", storeId));
    }

    @Override
    public void deleteClientIdByStoreId(Long storeId){
        Oauth2RegisteredClientEntity oauth2RegisteredClientEntity1 = baseDao.selectOne(new QueryWrapper<Oauth2RegisteredClientEntity>().eq("is_business_user", 0).eq("store_id", storeId));
        if (oauth2RegisteredClientEntity1 != null) {
            baseDao.updateStoreIdByClientid(oauth2RegisteredClientEntity1.getId(), null);
        }
    }
    @Override
    public Oauth2RegisteredClientEntity getClientByStoreId(Long storeId){
        return baseDao.selectOne(new QueryWrapper<Oauth2RegisteredClientEntity>().eq("is_business_user", 0).eq("store_id", storeId));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(Oauth2RegisteredClientDTO dto) {
        dto.setClientSecret(dto.getClientSecretPlaintext());
        saveRegisteredClient(dto);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(List<String> ids) {
        deleteBatchIds(ids);
    }
} 